home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / tosspd.zip / TOSS.C < prev    next >
C/C++ Source or Header  |  1992-12-16  |  35KB  |  1,364 lines

  1. #include"msg.h"
  2.  
  3. WIN title={NULL,0,0,50,2,0x38,0x0,0x70,0,0,"  TOSS 1.2 (Beta)  QWK->RBBS->REP Message Tosser    Copyright 1992  Jim Storch"};
  4. WIN stat={NULL,1,2,49,12,0x19,0x1b,0x1f,0,0,"STATUS"};
  5. WIN warn={NULL,1,15,49,21,0x4c,0x4b,0x4f,0,0,"WARNINGS"};
  6. WIN proc={NULL,52,2,77,21,0x2a,0x20,0x2f,0,0,"PROCESSING"};
  7.  
  8. CONFIG config={
  9.     FALSE,
  10.     FALSE,
  11.     FALSE,
  12.     "",
  13.     "",
  14.     "Brought to you by ELHARB (703)730-0542 Woodbridge,VA",
  15.     "",
  16.     "",
  17.     "PKZIP -ex",
  18.     "PKUNZIP -o",
  19.     "",
  20.     "",
  21.     NULL,NULL,NULL,NULL,NULL,
  22.     0,0,0,0};
  23.  
  24. int main(int argc, char *argv[])
  25.     {
  26.     clrscr();
  27.     wallpaper(&title);
  28.     openwin(&stat);
  29.     openwin(&warn);
  30.     openwin(&proc);
  31.     if(argc<2) failure("Missing Command Line Arguments-\n"
  32.             "USAGE: TOSS [export/import] HOST.CFG\n");
  33.  
  34.     if(strcmpi(argv[1],"EXPORT")==0)
  35.         export(argv[2]);
  36.     else
  37.         if(strcmpi(argv[1],"IMPORT")==0)
  38.             import(argv[2]);
  39.     else
  40.         failure("Improper Command Line Arguments-\n"
  41.             "USAGE: TOSS [export/import] HOST.CFG\n");
  42.     gotoxy(1,24);
  43.     return(0);
  44.     }
  45.  
  46. /********************************************************
  47.  Test to make sure the specified work directory is valid.
  48.  If bad, try to create.
  49.  ********************************************************/
  50. void checkworkdir(char *dir)
  51.     {
  52.     if(access(dir,0))
  53.         {
  54.         printfwin(&stat,"Creating work directory:\n  %s\n",dir);
  55.         if (mkdir(dir)!=0)
  56.             failure("Cannot create work directory:\n  %s\n",dir);
  57.         }
  58.     }
  59.  
  60. /**************************
  61.  Uncompress the .QWK packet
  62.  **************************/
  63. void unzip(void)
  64.     {
  65.     char comline[256];
  66.     int *tbuff,x,zipstat;
  67.     int far *screen;
  68.     struct text_info tinfo;
  69.     gettextinfo(&tinfo);
  70.     if(tinfo.currmode==MONO)
  71.         screen=(int far *)0xB0000000;
  72.     else
  73.         screen=(int far *)0xB8000000;
  74.     tbuff=e_malloc(4000*sizeof(char));
  75.     strcpy(comline,config.unzip);
  76.     strcat(comline," ");
  77.     strcat(comline,config.qwkname);
  78.     strcat(comline," ");
  79.     strcat(comline,config.workdir);
  80.     printfwin(&stat,"->Uncompressing:\n%s\n",comline);
  81.     for(x=0;x<2000;x++)
  82.         *(tbuff+x)= *(screen+x);
  83.     clrscr();
  84.     system(comline);
  85.     for(x=0;x<2000;x++)
  86.         *(screen+x)= *(tbuff+x);
  87.     free(tbuff);
  88.     }
  89.  
  90. /************************
  91.  Compress the .REP packet
  92.  ************************/
  93. void zip(void)
  94.     {
  95.     char comline[256];
  96.     int *tbuff,x;
  97.     int far *screen;
  98.     struct text_info tinfo;
  99.     gettextinfo(&tinfo);
  100.     if(tinfo.currmode==MONO)
  101.         screen=(int far *)0xB0000000;
  102.     else
  103.         screen=(int far *)0xB8000000;
  104.     tbuff=e_malloc(4000*sizeof(char));
  105.     strcpy(comline,config.zip);
  106.     strcat(comline," ");
  107.     strcat(comline,config.repname);
  108.     strcat(comline," ");
  109.     strcat(comline,config.workdir);
  110.     strcat(comline,"\\");
  111.     strcat(comline,config.hostname);
  112.     strcat(comline,".MSG" );
  113.     printfwin(&stat,"->Compressing:\n%s\n",comline);
  114.     for(x=0;x<2000;x++)
  115.         *(tbuff+x)= *(screen+x);
  116.     clrscr();
  117.     system(comline);
  118.     for(x=0;x<2000;x++)
  119.         *(screen+x)= *(tbuff+x);
  120.     free(tbuff);
  121.     }
  122.  
  123. /*********************************
  124.  Export from the RBBS message file
  125.  to a .REP packet for the host
  126.  *********************************/
  127. void export(char *host)
  128.     {
  129.     char twirl[]="\\\\||||////----";
  130.     int s=0;
  131.     struct ll_conf *conf;
  132.     struct ll_swap *swap;
  133.     MSG *msg;
  134.     FILE *infile, *outfile;
  135.     int count=0;
  136.     char rep[81],to,from;
  137.     char buff[128];
  138.     read_config(&config,host);
  139.     msg=(MSG *)e_malloc(sizeof(MSG));
  140.     strcpy(rep,config.workdir);
  141.     strcat(rep,"\\");
  142.     strcat(rep,config.hostname);
  143.     strcat(rep,".MSG");
  144.     if(access(config.repname,0)==0 && access(rep,0)==0 && config.append==TRUE)
  145.         {
  146.         printfwin(&stat,"->Appending: \"%s\"\n",rep);
  147.         if ((outfile=fopen(rep,"ab"))==NULL)
  148.             failure("Cannot append reply file:\n\"%s\"\n",rep);
  149.         }
  150.     else
  151.         {
  152.         printfwin(&stat,"->Creating: \"%s\"\n",rep);
  153.         if ((outfile=fopen(rep,"wb"))==NULL)
  154.             failure("Cannot make reply file:\n\"%s\"\n",rep);
  155.         padcpy(buff,config.hostname,128);
  156.         addblock(buff,outfile);
  157.         }
  158.     conf=config.conf;
  159.     while(conf!=NULL)
  160.         {
  161.         printfwin(&stat,"->Reading: \"%s\"\n",conf->path);
  162.         if ((infile=fopen(conf->path,"rb"))==NULL)
  163.             failure("Cannot open RBBS msg file:\n\"%s\"\n",conf->path);
  164.         pos_rbbs(infile);
  165.         while(read_rbbs(msg,infile)!=-1)
  166.             {
  167.             if(msg->number <= conf->last_read || !msg->active)
  168.                 {
  169.                 printfwin(&proc,"%c\b",twirl[s]);
  170.                 s++;
  171.                 if(s>14) s=0;
  172.                 free(msg->text_buffer);
  173.                 continue;
  174.                 }
  175.             if(msg->priv && !config.pass_private && !exempt(msg))
  176.                 {
  177.                 show_header(msg);
  178.                 printfwin(&proc,"** Private mail skipped **\n",msg->number);
  179.                 free(msg->text_buffer);
  180.                 continue;
  181.                 }
  182.             if(deny(msg) && !exempt(msg))
  183.                 {
  184.                 show_header(msg);
  185.                 printfwin(&proc,"** Denied EXPORT rights **\n");
  186.                 free(msg->text_buffer);
  187.                 continue;
  188.                 }
  189.             swap=config.export;
  190.             to=from=FALSE;
  191.             while(swap!=NULL)
  192.                 {
  193.                 if(strncmp(msg->from,swap->from,22)==0 && from==FALSE)
  194.                     {
  195.                     termcpy(msg->from,swap->to,31);
  196.                     from=TRUE;
  197.                     }
  198.                 if(strncmp(msg->to,swap->from,22)==0 && to==FALSE)
  199.                     {
  200.                     termcpy(msg->to,swap->to,25);
  201.                     to=TRUE;
  202.                     }
  203.                 swap=swap->next;
  204.                 }
  205.             show_header(msg);
  206.             conf->processed++;
  207.             count++;
  208.             conf->last_read=msg->number;
  209.             addtag(msg);
  210.             msg->number=conf->number;
  211.             msg->conf=conf->number;
  212.             write_qwk(msg,outfile);
  213.             free(msg->text_buffer);
  214.             }
  215.         printfwin(&stat,"  %d messages processed\n",conf->processed);
  216.         fclose(infile);
  217.         conf=conf->next;
  218.         }
  219.     free(msg);
  220.     make_lmr();
  221.     fclose(outfile);
  222.     printfwin(&stat,"  %d Total Messages Processed\n",count);
  223.     if(count!=0)
  224.         zip();
  225.     //printfwin(&proc," ");
  226.     printfwin(&stat,"->ALL DONE! Thank you for using TOSS.\n");
  227.     }
  228.  
  229. /*********************************
  230.  Import to the RBBS message file
  231.  from a .QWK packet from the host
  232.  *********************************/
  233. void import(char *host)
  234.     {
  235.     struct ll_conf *conf;
  236.     struct ll_swap *swap;
  237.     MSG *msg;
  238.     FILE *infile;
  239.     char dat[128],to,from;
  240.     int mcount=0;
  241.     int lastconf=0;
  242.     read_config(&config,host);
  243.     unzip();
  244.     msg=(MSG *)e_malloc(sizeof(MSG));
  245.     strcpy(dat,config.workdir);
  246.     strcat(dat,"\\");
  247.     strcat(dat,"MESSAGES.DAT");
  248.     printfwin(&stat,"->Reading: \"%s\"\n",dat);
  249.     if ((infile=fopen(dat,"rb"))==NULL)
  250.         failure("Cannot open message file:\n\"%s\"\n",dat);
  251.     pos_qwk(infile);
  252.     while(read_qwk(msg,infile)!=-1)
  253.         {
  254.         if(msg->priv && !config.pass_private && !exempt(msg))
  255.             {
  256.             show_header(msg);
  257.             printfwin(&proc,"** Private mail skipped **\n");
  258.             free(msg->text_buffer);
  259.             continue;
  260.             }
  261.         if(deny(msg) && !exempt(msg))
  262.             {
  263.             show_header(msg);
  264.             printfwin(&proc,"** Denied IMPORT rights! **\n");
  265.             free(msg->text_buffer);
  266.             continue;
  267.             }
  268.         swap=config.import;
  269.         to=from=FALSE;
  270.         while(swap!=NULL)
  271.             {
  272.             if(strncmp(msg->from,swap->from,22)==0 && from==FALSE)
  273.                 {
  274.                 termcpy(msg->from,swap->to,31);
  275.                 from=TRUE;
  276.                 }
  277.             if(strncmp(msg->to,swap->from,22)==0 && to==FALSE)
  278.                 {
  279.                 termcpy(msg->to,swap->to,25);
  280.                 to=TRUE;
  281.                 }
  282.             swap=swap->next;
  283.             }
  284.         conf=config.conf;
  285.         while(conf!=NULL)
  286.             {
  287.             if(msg->conf==conf->number)
  288.                 {
  289.                 if(lastconf!=msg->conf)
  290.                     {
  291.                     printfwin(&stat,"->Writing: \"%s\"\n",conf->path);
  292.                     lastconf=msg->conf;
  293.                     }
  294.                 conf->last_read=write_rbbs(msg,conf->path);
  295.                 show_header(msg);
  296.                 mcount++;
  297.                 break;
  298.                 }
  299.             conf=conf->next;
  300.             }
  301.         free(msg->text_buffer);
  302.         }
  303.     printfwin(&stat,"  %d messages processed\n",mcount);
  304.     fclose(infile);
  305.     free(msg);
  306.     make_lmr();
  307.     remove(dat);
  308.     if(config.killqwk==TRUE)
  309.         {
  310.         printfwin(&stat,"->Deleting: \"%s\"\n",config.qwkname);
  311.         remove(config.qwkname);
  312.         }
  313.     printfwin(&stat,"->ALL DONE! Thank you for using TOSS.\n");
  314.     }
  315.  
  316. /****************************************************
  317.  Return TRUE if message is to/from a user denied mail
  318.  ****************************************************/
  319. int deny(MSG *msg)
  320.     {
  321.     struct ll_who *who;
  322.     who=config.loser;
  323.     while(who!=NULL)
  324.         {
  325.         if(strncmpi(who->user,msg->from,22)==0)
  326.             return(TRUE);
  327.         if(strncmpi(who->user,msg->to,22)==0)
  328.             return(TRUE);
  329.         who=who->next;
  330.         }
  331.     return(FALSE);
  332.     }
  333.  
  334. /****************************************
  335.  Return TRUE if message is to/from a user
  336.  exempt from the private mail filter
  337.  ****************************************/
  338. int exempt(MSG *msg)
  339.     {
  340.     struct ll_who *who;
  341.     who=config.exempt;
  342.     while(who!=NULL)
  343.         {
  344.         if(strncmpi(who->user,msg->from,22)==0)
  345.             return(TRUE);
  346.         if(strncmpi(who->user,msg->to,22)==0)
  347.             return(TRUE);
  348.         who=who->next;
  349.         }
  350.     return(FALSE);
  351.     }
  352.  
  353. /*************************************************
  354.  Read in the configuration file and convert to the
  355.  info held in CONFIG.
  356.  *************************************************/
  357. void read_config(CONFIG *config,char *cfgfile)
  358.     {
  359.     FILE *infile;
  360.     struct ll_who *who,**w_ptr;
  361.     struct ll_swap *swap,**s_ptr;
  362.     struct ll_conf *conf,**c_ptr;
  363.     struct LMR lmr;
  364.     int count=0;
  365.     char line[100];
  366.     printfwin(&stat,"->Reading: \"%s\"\n",cfgfile);
  367.     if ((infile=fopen(cfgfile,"rt"))==NULL)
  368.         failure("Cannot open host configuration file:\n\"%s\"\n",cfgfile);
  369.  
  370.     while(instr(line,infile)!=-1)
  371.         {
  372.         count++;
  373.         remls(line);
  374.         if(strlen(line)<5)
  375.             continue;
  376.         if(*line==';')
  377.             continue;
  378.         if(strncmpi(line,"TAGL",4)==0)
  379.             {
  380.             strtok(line,"=");
  381.             strncpy(config->tagline,strtok(NULL,"\0"),70);
  382.             continue;
  383.             }
  384.         strupr(line);
  385.         if(strncmpi(line,"CONF",4)==0)
  386.             {
  387.             conf=(struct ll_conf *)malloc(sizeof(struct ll_conf));
  388.             strtok(line,"=");
  389.             conf->number=atoi(strtok(NULL,","));
  390.             strncpy(conf->path,strtok(NULL,"\0"),80);
  391.             conf->next=NULL;
  392.             conf->processed=0;
  393.             conf->last_read=0;
  394.             c_ptr=&config->conf;
  395.             while(*c_ptr!=NULL)
  396.                 c_ptr=&(*c_ptr)->next;
  397.             *c_ptr=conf;
  398.             config->conf_count++;
  399.             continue;
  400.             }
  401.         if(strncmpi(line,"IMPO",4)==0)
  402.             {
  403.             swap=(struct ll_swap *)malloc(sizeof(struct ll_swap));
  404.             strtok(line,"=");
  405.             padzcpy(swap->from,strtok(NULL,","),32);
  406.             padzcpy(swap->to,strtok(NULL,"\0"),32);
  407.             swap->next=NULL;
  408.             s_ptr=&config->import;
  409.             while(*s_ptr!=NULL)
  410.                 s_ptr=&(*s_ptr)->next;
  411.             *s_ptr=swap;
  412.             continue;
  413.             }
  414.         if(strncmpi(line,"EXPO",4)==0)
  415.             {
  416.             swap=(struct ll_swap *)malloc(sizeof(struct ll_swap));
  417.             strtok(line,"=");
  418.             padzcpy(swap->from,strtok(NULL,","),32);
  419.             padzcpy(swap->to,strtok(NULL,"\0"),32);
  420.             swap->next=NULL;
  421.             s_ptr=&config->export;
  422.             while(*s_ptr!=NULL)
  423.                 s_ptr=&(*s_ptr)->next;
  424.             *s_ptr=swap;
  425.             continue;
  426.             }
  427.         if(strncmpi(line,"EXEM",4)==0)
  428.             {
  429.             who=(struct ll_who *)malloc(sizeof(struct ll_who));
  430.             strtok(line,"=");
  431.             padzcpy(who->user,strtok(NULL,"\0"),32);
  432.             who->next=NULL;
  433.             w_ptr=&config->exempt;
  434.             while(*w_ptr!=NULL)
  435.                 w_ptr=&(*w_ptr)->next;
  436.             *w_ptr=who;
  437.             continue;
  438.             }
  439.         if(strncmpi(line,"DENY",4)==0)
  440.             {
  441.             who=(struct ll_who *)malloc(sizeof(struct ll_who));
  442.             strtok(line,"=");
  443.             padzcpy(who->user,strtok(NULL,"\0"),32);
  444.             who->next=NULL;
  445.             w_ptr=&config->loser;
  446.             while(*w_ptr!=NULL)
  447.                 w_ptr=&(*w_ptr)->next;
  448.             *w_ptr=who;
  449.             continue;
  450.             }
  451.         if(strncmpi(line,"WORK",4)==0)
  452.             {
  453.             strtok(line,"=");
  454.             strncpy(config->workdir,strtok(NULL,"\0"),80);
  455.             if(*(config->workdir+strlen(config->workdir)-1)=='\\')
  456.                 *(config->workdir+strlen(config->workdir)-1)='\0';
  457.             continue;
  458.             }
  459.         if(strncmpi(line,"QWKN",4)==0)
  460.             {
  461.             strtok(line,"=");
  462.             strncpy(config->qwkname,strtok(NULL,"\0"),80);
  463.             continue;
  464.             }
  465.         if(strncmpi(line,"REPN",4)==0)
  466.             {
  467.             strtok(line,"=");
  468.             strncpy(config->repname,strtok(NULL,"\0"),80);
  469.             continue;
  470.             }
  471.         if(strncmpi(line,"LOGF",4)==0)
  472.             {
  473.             strtok(line,"=");
  474.             strncpy(config->logfile,strtok(NULL,"\0"),80);
  475.             continue;
  476.             }
  477.         if(strncmpi(line,"HOST",4)==0)
  478.             {
  479.             strtok(line,"=");
  480.             strncpy(config->hostname,strtok(NULL,"\0"),9);
  481.             strcpy(config->lmrname,config->hostname);
  482.             strcat(config->lmrname,".LMR");
  483.             continue;
  484.             }
  485.         if(strncmpi(line,"COMP",4)==0)
  486.             {
  487.             strtok(line,"=");
  488.             strncpy(config->zip,strtok(NULL,"\0"),80);
  489.             continue;
  490.             }
  491.         if(strncmpi(line,"UNCO",4)==0)
  492.             {
  493.             strtok(line,"=");
  494.             strncpy(config->unzip,strtok(NULL,"\0"),80);
  495.             continue;
  496.             }
  497.         if(strncmpi(line,"ALLO",4)==0)
  498.             {
  499.             strtok(line,"=");
  500.             padzcpy(line,strtok(NULL,"\0"),4);
  501.             if(strncmpi(line,"YES",3)==0)
  502.                 config->pass_private=TRUE;
  503.             else
  504.                 config->pass_private=FALSE;
  505.             continue;
  506.             }
  507.         if(strncmpi(line,"APPE",4)==0)
  508.             {
  509.             strtok(line,"=");
  510.             padzcpy(line,strtok(NULL,"\0"),4);
  511.             if(strncmpi(line,"YES",3)==0)
  512.                 config->append=TRUE;
  513.             else
  514.                 config->append=FALSE;
  515.             continue;
  516.             }
  517.         if(strncmpi(line,"KILLQ",4)==0)
  518.             {
  519.             strtok(line,"=");
  520.             padzcpy(line,strtok(NULL,"\0"),4);
  521.             if(strncmpi(line,"YES",3)==0)
  522.                 config->killqwk=TRUE;
  523.             else
  524.                 config->killqwk=FALSE;
  525.             continue;
  526.             }
  527.         printfwin(&warn,"--UNRECOGNIZED COMMAND--\n");
  528.         printfwin(&warn,"Line number %d of config file:  \"%s\"\n",count,cfgfile);
  529.         printfwin(&warn,"\"%s\"\n",line);
  530.         }
  531.     fclose(infile);
  532.     if(strlen(config->repname)==0)
  533.         failure("'REPNAME=' not in config file:\n  \"%s\"\n",cfgfile);
  534.  
  535.     if(strlen(config->qwkname)==0)
  536.         failure("'QWKNAME=' not in config file:\n  \"%s\"\n",cfgfile);
  537.  
  538.     if(strlen(config->hostname)==0)
  539.         failure("'HOSTNAME=' not in config file:\n  \"%s\"\n",cfgfile);
  540.  
  541.     if(strlen(config->workdir)==0)
  542.         failure("'WORKDIR=' not in config file:\n  \"%s\"\n",cfgfile);
  543.  
  544.     if(config->conf==NULL)
  545.         failure("No 'CONF=' specified in config file:\n  \"%s\"\n",cfgfile);
  546.  
  547.     if(config->export==NULL)
  548.         {
  549.         printfwin(&warn,"--WARNING--\n");
  550.         printfwin(&warn,"No 'EXPORT=' conversions in config file:\n  \"%s\"\n",cfgfile);
  551.         }
  552.     if(config->import==NULL)
  553.         {
  554.         printfwin(&warn,"--WARNING--\n");
  555.         printfwin(&warn,"No 'IMPORT=' conversions in config file:\n  \"%s\"\n",cfgfile);
  556.         }
  557.  
  558.     printfwin(&stat,"->Reading: \"%s\"\n",config->lmrname);
  559.     if(access(config->lmrname,0)!=0)
  560.         {
  561.         printfwin(&stat,"  Not found, starting from zero\n");
  562.         return;
  563.         }
  564.     if ((infile=fopen(config->lmrname,"rb"))==NULL)
  565.         failure("Error accessing .LRM file: \"%s\"\n",config->lmrname);
  566.     while(1)
  567.         {
  568.         fread(&lmr,sizeof(struct LMR),1,infile);
  569.         if(feof(infile))
  570.             break;
  571.         conf=config->conf;
  572.         while(conf!=NULL)
  573.             {
  574.             if(conf->number==lmr.number)
  575.                 conf->last_read=lmr.last_read;
  576.             conf=conf->next;
  577.             }
  578.         }
  579.     fclose(infile);
  580.     checkworkdir(config->workdir);
  581.     }
  582.  
  583. /*************************************************
  584.  Make Last_Message_Read (.LMR) file for this host,
  585.  so we know where to start next time around
  586.  *************************************************/
  587. void make_lmr(void)
  588.     {
  589.     struct ll_conf *conf;
  590.     struct LMR lmr;
  591.     FILE *outfile;
  592.     printfwin(&stat,"->Updating: \"%s\"\n",config.lmrname);
  593.     if ((outfile=fopen(config.lmrname,"wb"))==NULL)
  594.         failure("Error Creating .LRM file: \"%s\"\n",config.lmrname);
  595.  
  596.     conf=config.conf;
  597.     while(conf!=NULL)
  598.         {
  599.         lmr.number=conf->number;
  600.         lmr.last_read=conf->last_read;
  601.         fwrite(&lmr,sizeof(struct LMR),1,outfile);
  602.         conf=conf->next;
  603.         }
  604.     fclose(outfile);
  605.     }
  606.  
  607. /****************************************************************************
  608.                  QWK code starts here
  609.  ****************************************************************************/
  610. /****************************************
  611.  Set to the first message of a qwk packet
  612.  ****************************************/
  613. void pos_qwk(FILE *infile)
  614.     {
  615.     fseek(infile,128,SEEK_SET);
  616.     }
  617.  
  618. /***********************************************
  619.  Read in the next QWK message and convert to MSG
  620.  Returns -1 on End-Of-File
  621.  ***********************************************/
  622. int read_qwk(MSG *msg,FILE *infile)
  623.     {
  624.     struct QWK *qwk;
  625.     char temp[10];
  626.     long size;
  627.     int x;
  628.     qwk=(struct QWK *) e_malloc(sizeof(struct QWK));
  629.     fread(qwk,128,1,infile);
  630.     if(feof(infile))
  631.         return(-1);
  632.  
  633.     // if Net-status block encountered, exit
  634.  
  635.     if((qwk->active_flag!=225 && qwk->active_flag!=226) ||
  636.     qwk->date[2]!='-'                           ||
  637.     qwk->date[5]!='-')
  638.         return(-1);
  639.  
  640.     msg->priv=FALSE;
  641.     if(qwk->active_flag==225)
  642.         msg->active=TRUE;
  643.     else
  644.         msg->active=FALSE;
  645.     termcpy(temp,qwk->msg_blk_size,6);
  646.     size=atol(temp);
  647.     msg->size=size;
  648.     termcpy(msg->from,qwk->from,25);
  649.     termcpy(msg->to,qwk->to,25);
  650.     termcpy(msg->subject,qwk->subject,22);
  651.     termcpy(msg->password,qwk->password,12);
  652.     msg->level=0;
  653.     msg->conf=qwk->conf_num;
  654.     termcpy(temp,qwk->number,4);
  655.     msg->number=atoi(temp);
  656.  
  657.     msg->read.hour=32;      // This is for RBBS:
  658.     msg->read.minute=32;    // If set to all spaces,
  659.     msg->read.second=32;    // RBBS assumes its unread.
  660.  
  661.     msg->read.month=32;
  662.     msg->read.day=32;
  663.     msg->read.year=32;
  664.  
  665.     strncpy(temp,qwk->time,5);
  666.     temp[2]='\0';
  667.     temp[5]='\0';
  668.     msg->sent.hour=atoi(temp);
  669.     msg->sent.minute=atoi(&temp[3]);
  670.     msg->sent.second=0;
  671.  
  672.     strncpy(temp,qwk->date,8);
  673.     temp[2]='\0';
  674.     temp[5]='\0';
  675.     temp[8]='\0';
  676.     msg->sent.month=atoi(temp);
  677.     msg->sent.day=atoi(&temp[3]);
  678.     msg->sent.year=atoi(&temp[6]);
  679.  
  680.     msg->text_buffer=(char *)e_malloc(size*128);
  681.     memset(msg->text_buffer,' ',size*128);
  682.     size--;
  683.     for(x=0;x<size;x++)
  684.         {
  685.         fread(msg->text_buffer+(128*x),128,1,infile);
  686.         if(feof(infile)) return(-1);
  687.         }
  688.     free(qwk);
  689.     return(size);
  690.     }
  691.  
  692. /*************************************
  693.  Write a message to a QWK message base
  694.  This will be a simple append.
  695.  *************************************/
  696. void write_qwk(MSG *msg,FILE *outfile)
  697.     {
  698.     struct QWK *qwk;
  699.     char temp[33];
  700.     int textblocks,x;
  701.     qwk=(struct QWK *) e_malloc(sizeof(struct QWK));
  702.     if(msg->priv)
  703.         qwk->status_flag='+';
  704.     else
  705.         qwk->status_flag=' ';
  706.     padcpy(qwk->ref_msg_num,"",8);
  707.     qwk->network_flag=' ';
  708.     qwk->active_flag=225;
  709.     qwk->conf_num=msg->conf;
  710.     padcpy(qwk->number,ltoa(msg->number,temp,10),7);
  711.     padcpy(qwk->from,msg->from,25);
  712.     padcpy(qwk->to,msg->to,25);
  713.     padcpy(qwk->subject,msg->subject,25);
  714.     padcpy(qwk->password,"",12);   // <- mod !#!#!#!
  715.     padcpy(qwk->msg_blk_size,ltoa(msg->size,temp,10),6);
  716.     sprintf(temp,"%d%d:%d%d\0",
  717.         msg->sent.hour/10,
  718.         msg->sent.hour%10,
  719.         msg->sent.minute/10,
  720.         msg->sent.minute%10);
  721.     strncpy(qwk->time,temp,5);
  722.  
  723.     sprintf(temp,"%d%d-%d%d-%d%d\n",
  724.         msg->sent.month/10,
  725.         msg->sent.month%10,
  726.         msg->sent.day/10,
  727.         msg->sent.day%10,
  728.         msg->sent.year/10,
  729.         msg->sent.year%10);
  730.     strncpy(qwk->date,temp,8);
  731.  
  732.     addblock(qwk,outfile);
  733.     textblocks=msg->size-1;
  734.     for(x=0;x<textblocks;x++)
  735.         addblock(msg->text_buffer+(128*x),outfile);
  736.     free(qwk);
  737.     }
  738.  
  739. /****************************************************************************
  740.  
  741.             RBBS code starts here
  742.  ****************************************************************************/
  743. /**************************************************************
  744.  Set file pointer to the first message of an RBBS message base.
  745.  This value is recorded in the Check Point Record (first block)
  746.  **************************************************************/
  747. void pos_rbbs(FILE *infile)
  748.     {
  749.     CPR *cpr;
  750.     cpr=(CPR*)e_malloc(sizeof(CPR));
  751.     read_rbbs_header(cpr,infile);
  752.     fseek(infile,128*cpr->first_msg_blk,SEEK_SET);
  753.     free(cpr);
  754.     }
  755.  
  756. /******************************************
  757.  Read in an RBBS message and convert to MSG
  758.  ******************************************/
  759. int read_rbbs(MSG *msg,FILE *infile)
  760.     {
  761.     struct message_header *head;
  762.     char temp[10];
  763.     int size,x;
  764.     fpos_t filepos;
  765.     head=(struct message_header *) e_malloc(sizeof(struct message_header));
  766.  
  767.     fread(head,128,1,infile);
  768.     if(feof(infile))
  769.         return(-1);
  770.  
  771.     if((head->active!=225 && head->active!=226) ||
  772.         head->date_sent[2]!='-'               ||
  773.         head->date_sent[5]!='-')
  774.         failure("Error retrieving Message Header.\n");
  775.  
  776.     if(head->private_flag=='*') msg->priv=TRUE;
  777.         else msg->priv=FALSE;
  778.     if(head->active==225) msg->active=TRUE;
  779.         else msg->active=FALSE;
  780.     termcpy(temp,head->msg_blk_size,4);
  781.     size=atoi(temp);
  782.     msg->size=size;
  783.  
  784.     termcpy(msg->from,head->from,31);
  785.     termcpy(msg->to,head->to,22);
  786.     termcpy(msg->subject,head->subject,25);
  787.     termcpy(msg->password,head->password,15);
  788.     msg->level=head->read_sec_lev;
  789.     msg->conf=0;
  790.     termcpy(temp,head->msg_number,4);
  791.     msg->number=atoi(temp);
  792.  
  793.     msg->read.hour=head->hour;
  794.     msg->read.minute=head->minute;
  795.     msg->read.second=head->second;
  796.  
  797.     msg->read.month=head->month;
  798.     msg->read.day=head->day;
  799.     msg->read.year=head->year;
  800.  
  801.     strncpy(temp,head->time_sent,8);
  802.     temp[2]='\0';
  803.     temp[5]='\0';
  804.     temp[8]='\0';
  805.     msg->sent.hour=atoi(temp);
  806.     msg->sent.minute=atoi(&temp[3]);
  807.     msg->sent.second=atoi(&temp[6]);
  808.  
  809.     strncpy(temp,head->date_sent,8);
  810.     temp[2]='\0';
  811.     temp[5]='\0';
  812.     temp[8]='\0';
  813.     msg->sent.month=atoi(temp);
  814.     msg->sent.day=atoi(&temp[3]);
  815.     msg->sent.year=atoi(&temp[6]);
  816. /********************************************************************
  817.  Skip multiple headers for Carbon Copy Function new to RBBS 17.4
  818.  NOTE: This is brute force technology at its finest. I tried to
  819.  use the Header_Number value, (which was always 32, SPACE, in earlier
  820.  versions of RBBS), but it really got out of hand. The docs for 17.4
  821.  suggest the following check for a REAL additional header, regardless
  822.  of the Header_number value. Which works a LOT better.
  823.  ********************************************************************/
  824. while(1)
  825.     {
  826.     fgetpos(infile,&filepos);
  827.     fread(head,128,1,infile);
  828.     if((head->active==225 || head->active==226) &&
  829.     head->date_sent[2]=='-'               &&
  830.     head->date_sent[5]=='-')
  831.         {
  832.         size--;
  833.         continue;
  834.         }
  835.     fsetpos(infile,&filepos);
  836.     break;
  837.     }
  838.     msg->text_buffer=(char *)e_malloc(size*128);
  839.     memset(msg->text_buffer,' ',size*128);
  840.     size--;
  841.     for(x=0;x<size;x++)
  842.         {
  843.         fread(msg->text_buffer+(128*x),128,1,infile);
  844.         if(feof(infile)) return(-1);
  845.         }
  846.     free(head);
  847.     return(size);
  848.     }
  849.  
  850. /***************************************
  851.  Write a message to an RBBS message base
  852.  Returns the message number used.
  853.  ***************************************/
  854. int write_rbbs(MSG *msg,char *file)
  855.     {
  856.     FILE *outfile;
  857.     struct message_header *head;
  858.     CPR *cpr;
  859.     char temp[33];
  860.     int textblocks,x;
  861.  
  862.     if ((outfile=fopen(file,"r+b"))==NULL)
  863.         {
  864.         printfwin(&warn,"\n----ERROR----\n");
  865.         printfwin(&warn,"Cannot open RBBS message file:\n  \"%s\"\n",file);
  866.         exit(1);
  867.         }
  868.     head=(struct message_header *) e_malloc(sizeof(struct message_header));
  869.     cpr=(CPR *)e_malloc(sizeof(CPR));
  870.     read_rbbs_header(cpr,outfile);
  871.     cpr->last_msg_num++;
  872.     head->active=225;
  873. /**************************************************************************
  874.  This line regards 17.4's multiple header value for "Carbon Copy" messages.
  875.  Unfortunately, it appears that older versions of RBBS will choke if this
  876.  value is anything but 32 (SPACE), even though the bytes is described as
  877.  "reserved". Since 17.4 will check for a valid header anyway, We can set
  878.  this to 32 and make both versions semi-happy.
  879.  **************************************************************************/
  880.     head->header_number=32;
  881.  
  882.     head->read_sec_lev=msg->level;
  883.     if (msg->priv)
  884.         head->private_flag='*';
  885.     else
  886.         head->private_flag=' ';
  887.  
  888.     padcpy(head->msg_number,ltoa(cpr->last_msg_num,temp,10),4);
  889.     msg->number=cpr->last_msg_num;
  890.     padcpy(head->from,msg->from,31);
  891.     padcpy(head->to,msg->to,22);
  892.     padcpy(head->subject,msg->subject,25);
  893.     padcpy(head->password,msg->password,15);
  894.     lpadcpy(head->msg_blk_size,ltoa(msg->size,temp,10),4);
  895.     sprintf(temp,"%d%d:%d%d:%d%d\n",
  896.         msg->sent.hour/10,
  897.         msg->sent.hour%10,
  898.         msg->sent.minute/10,
  899.         msg->sent.minute%10,
  900.         msg->sent.second/10,
  901.         msg->sent.second%10);
  902.     strncpy(head->time_sent,temp,8);
  903.  
  904.     sprintf(temp,"%d%d-%d%d-%d%d\n",
  905.         msg->sent.month/10,
  906.         msg->sent.month%10,
  907.         msg->sent.day/10,
  908.         msg->sent.day%10,
  909.         msg->sent.year/10,
  910.         msg->sent.year%10);
  911.     strncpy(head->date_sent,temp,8);
  912.  
  913.     head->month=msg->read.month;
  914.     head->day=msg->read.day;
  915.     head->year=msg->read.year;
  916.     head->hour=msg->read.hour;
  917.     head->minute=msg->read.minute;
  918.     head->second=msg->read.second;
  919.  
  920.     putblock(head,cpr->next_msg_blk,outfile);
  921.     textblocks=msg->size-1;
  922.  
  923.     for(x=0;x<textblocks;x++)
  924.         addblock(msg->text_buffer+(128*x),outfile);
  925.     cpr->last_msg_blk=cpr->next_msg_blk;
  926.     cpr->next_msg_blk+=msg->size;
  927.     write_rbbs_header(cpr,outfile);
  928.  
  929.     free(cpr);
  930.     free(head);
  931.     fclose(outfile);
  932.     return(msg->number);
  933.     }
  934.  
  935. /********************************************************
  936.  Read in the Checkpoint Record block of the open file and
  937.  get some valuable info for the CPR struct.
  938.  ********************************************************/
  939. void read_rbbs_header(CPR *cpr, FILE *infile)
  940.     {
  941.     struct checkpoint_record *c_rec;
  942.     char temp[9];
  943.     c_rec=(struct checkpoint_record *) e_malloc(sizeof(struct checkpoint_record));
  944.     getblock(c_rec,0,infile);
  945.     termcpy(temp,c_rec->last_msg_num,8);
  946.     cpr->last_msg_num=atoi(temp);
  947.     termcpy(temp,c_rec->msg_start_blk,7);
  948.     cpr->first_msg_blk=atoi(temp)-1;
  949.     termcpy(temp,c_rec->last_msg_blk,7);
  950.     cpr->last_msg_blk=atoi(temp)-1;
  951.     termcpy(temp,c_rec->next_msg_blk,7);
  952.     cpr->next_msg_blk=atoi(temp)-1;
  953.     termcpy(temp,c_rec->msg_max,7);
  954.     cpr->msg_max=atoi(temp);
  955.     free(c_rec);
  956.     }
  957.  
  958. /*****************************************************
  959.  Write the modified data from the CPR structure to the
  960.  Checkpoint Record block of the open file.
  961.  *****************************************************/
  962. void write_rbbs_header(CPR *cpr, FILE *infile)
  963.     {
  964.     struct checkpoint_record *c_rec;
  965.     char temp[33];
  966.     c_rec=(struct checkpoint_record *)e_malloc(sizeof(struct checkpoint_record));
  967.     getblock(c_rec,0,infile);
  968.     lpadcpy(c_rec->last_msg_num,ltoa(cpr->last_msg_num,temp,10),8);
  969.     lpadcpy(c_rec->next_msg_blk,ltoa(cpr->next_msg_blk+1,temp,10),7);
  970.     putblock(c_rec,0,infile);
  971.     free(c_rec);
  972.     }
  973.  
  974.  
  975. /****************************************************************************
  976.             General code starts here
  977.  ****************************************************************************/
  978. void addtag(MSG *msg)
  979.     {
  980.     char *look,*end;
  981.     char tag[120];
  982.     strcpy(tag,"π  [TOSS 1.2B] ");
  983.     strcat(tag,config.tagline);
  984.     strcat(tag,"π");
  985.     end=msg->text_buffer+128*(msg->size);
  986.     look=end;
  987.     while(*look!='π')
  988.         {
  989.         if(look < msg->text_buffer) return;
  990.         look--;
  991.         }
  992.     if((end-look)<207) msg->size++;
  993.         strncpy(look,tag,strlen(tag));
  994.     }
  995.  
  996. /**********************************************************
  997.  Dump a message to the display. This functions is not used,
  998.  but retained for in case I need to troubleshoot.
  999.  **********************************************************/
  1000. void show_msg(MSG *msg)
  1001.     {
  1002.     int x,c,size=msg->size-1;
  1003.     printfwin(&proc,"\nMSG# %d\n",msg->number);
  1004.     printfwin(&proc,"DATE: %d-%d-%d  TIME: %d:%d:%d\n",
  1005.         msg->sent.month,
  1006.         msg->sent.day,
  1007.         msg->sent.year,
  1008.         msg->sent.hour,
  1009.         msg->sent.minute,
  1010.         msg->sent.second);
  1011.     printfwin(&proc,"\nFROM: %s     TO: %s\n",msg->from,msg->to);
  1012.     printfwin(&proc,"SUBJECT: %s\n",msg->subject);
  1013.     for(x=0;x<(size*128);x++)
  1014.         {
  1015.         c=(*(msg->text_buffer+x));
  1016.         if(c=='π')
  1017.             {
  1018.             printfwin(&proc,"\n");
  1019.             continue;
  1020.             }
  1021.         printfwin(&proc,"%c",c);
  1022.         }
  1023.     }
  1024.  
  1025. /***********************************************
  1026.  Show the message header info in the PROC window
  1027.  ***********************************************/
  1028. void show_header(MSG *msg)
  1029.     {
  1030.     char cut[21];
  1031.     printfwin(&proc," \nMessage: %d\n",msg->number);
  1032.     termcpy(cut,msg->from,14);
  1033.     printfwin(&proc,"   From: %s\n",cut);
  1034.     termcpy(cut,msg->to,14);
  1035.     printfwin(&proc,"     To: %s\n",cut);
  1036.     termcpy(cut,msg->subject,14);
  1037.     printfwin(&proc,"Subject: %s\n",cut);
  1038.     }
  1039.  
  1040. /*******************************************************************
  1041.  E_MALLOC() does the same  as malloc, except error tests so we don't
  1042.  have to  all the time.
  1043.  *******************************************************************/
  1044. void *e_malloc(size_t size)
  1045.     {
  1046.     void *pointer;
  1047.     if ((pointer = (char *) malloc(size)) == NULL)
  1048.         failure("Failure Allocating Free Memory");
  1049.     return(pointer);
  1050.     }
  1051.  
  1052. /**********************************************************
  1053.  Here's a generic routine to retrieve a 128 byte block from
  1054.  the specified, open file.
  1055.  **********************************************************/
  1056. void getblock(void *buff,long block,FILE *infile)
  1057.     {
  1058.     fseek(infile,(long)block*128,SEEK_SET);
  1059.     fread(buff,128,1,infile);
  1060.     }
  1061.  
  1062. /*******************************************************
  1063.  Here's a generic routine to write a 128 byte block from
  1064.  memory to the specified, open file.
  1065.  *******************************************************/
  1066. void putblock(void *buff,long block,FILE *outfile)
  1067.     {
  1068.     fseek(outfile,(long)block*128,SEEK_SET);
  1069.     fwrite(buff,128,1,outfile);
  1070.     }
  1071.  
  1072. /*******************************************************
  1073.  Here's a generic routine to write a 128 byte block from
  1074.  memory to the specified, open file at the current pos.
  1075.  *******************************************************/
  1076. void addblock(void *buff,FILE *outfile)
  1077.     {
  1078.     fwrite(buff,128,1,outfile);
  1079.     }
  1080.  
  1081. /***************************
  1082.  Report an error to and exit
  1083.  ***************************/
  1084. void failure(char *str,...)
  1085.     {
  1086.     char buff[256];
  1087.     va_list parms;
  1088.     va_start(parms,str);
  1089.     fcloseall();
  1090.     vsprintf(buff,str,parms);
  1091.     printwin(&warn,"--ERROR--\nProgram Terminating Because:\n  ");
  1092.     printwin(&warn,buff);
  1093.     gotoxy(1,24);
  1094.     exit(1);
  1095.     }
  1096.  
  1097. /******************************************************
  1098.  Copy (length) number of chars from one string to
  1099.  another and pad with trailing spaces. Doesn't add NULL
  1100.  ******************************************************/
  1101. void padcpy(char *to, char *from,int length)
  1102.     {
  1103.     while(*from!=NULL && length>0)
  1104.         {
  1105.         *to=*from;
  1106.         to++;
  1107.         from++;
  1108.         length--;
  1109.         }
  1110.     while(length>0)
  1111.         {
  1112.         *to=' ';
  1113.         to++;
  1114.         length--;
  1115.         }
  1116.     }
  1117. /******************************************
  1118.  Same as padcpy(), buts add a leading space
  1119.  ******************************************/
  1120. void lpadcpy(char *to, char *from,int length)
  1121.     {
  1122.     *to=' ';
  1123.     to++;
  1124.     length--;
  1125.     while(*from!=NULL && length>0)
  1126.         {
  1127.         *to=*from;
  1128.         to++;
  1129.         from++;
  1130.         length--;
  1131.         }
  1132.     while(length>0)
  1133.         {
  1134.         *to=' ';
  1135.         to++;
  1136.         length--;
  1137.         }
  1138.     }
  1139.  
  1140. /*****************************************************
  1141.  Copy (length) of one string to another and add a NULL
  1142.  to the end. To read non-termed strings into C format.
  1143.  *****************************************************/
  1144. void termcpy(char *to, char *from, int length)
  1145.     {
  1146.     while(length)
  1147.         {
  1148.         *to=*from;
  1149.         to++;
  1150.         from++;
  1151.         length--;
  1152.         }
  1153.     *to='\0';
  1154.     }
  1155.  
  1156. /********************************************
  1157.  Fill in a dtg with the current date and time
  1158.  ********************************************/
  1159. void get_dtg(DTG *dtg)
  1160.     {
  1161.     struct tm *t;
  1162.     time_t timer;
  1163.     timer=time(NULL);
  1164.     t=localtime(&timer);
  1165.     dtg->hour=t->tm_hour;
  1166.     dtg->minute=t->tm_min;
  1167.     dtg->second=t->tm_sec;
  1168.     dtg->month=t->tm_mon;
  1169.     dtg->day=t->tm_mday;
  1170.     dtg->year=t->tm_year;
  1171.     }
  1172.  
  1173. /*************************************************
  1174.  Remove leading whilespaces from the target string
  1175.  *************************************************/
  1176. void remls(char *str)
  1177.     {
  1178.     char *ptr=str;
  1179.     while(*ptr!='\0')
  1180.         {
  1181.         if(*ptr==' ' || *ptr=='\t')
  1182.             strcpy(str,++ptr);
  1183.         else
  1184.             break;
  1185.         }
  1186.      }
  1187. /********************************************************
  1188.  Copy (length) number of chars from one string to another
  1189.  and pad with trailing spaces. And adds a NULL to the end
  1190.  PLUS: Skips leading spaces or tabs.
  1191.  ********************************************************/
  1192. void padzcpy(char *to, char *from,int length)
  1193.     {
  1194.     while(*from==' ' || *from=='\t')
  1195.         from++;
  1196.     while(*from!=NULL && length>1)
  1197.         {
  1198.         *to=*from;
  1199.         to++;
  1200.         from++;
  1201.         length--;
  1202.         }
  1203.     while(length>1)
  1204.         {
  1205.         *to=' ';
  1206.         to++;
  1207.         length--;
  1208.         }
  1209.     *to='\0';
  1210.     }
  1211.  
  1212. /****************************************************
  1213.  Read in one line from a text file, returns -1 on EOF
  1214.  I use this because fgets() and fscanf() work lousy
  1215.  ****************************************************/
  1216. int instr(char *targ, FILE *infile)
  1217.     {
  1218.     int c;
  1219.     while(!feof(infile))
  1220.         {
  1221.         c=getc(infile);
  1222.         *targ=c;
  1223.         if(c=='\n')
  1224.             {
  1225.             *targ='\0';
  1226.             return(0);
  1227.             }
  1228.         targ++;
  1229.         }
  1230.     return(-1);
  1231.     }
  1232.  
  1233. /********************************************
  1234.  Direct screen writing text windows routines.
  1235.  Very primitive, but fast and easy, which is
  1236.  nothing to sneeze at.
  1237.  ********************************************/
  1238. void printfwin(WIN *win, char *str,...)
  1239.     {
  1240.     char buff[256];
  1241.     va_list parms;
  1242.     va_start(parms,str);
  1243.     vsprintf(buff,str,parms);
  1244.     printwin(win,buff);
  1245.     }
  1246.  
  1247. void printwin(WIN *win, char *str)
  1248.     {
  1249.     while(*str!='\0')
  1250.         {
  1251.         if(win->cx>=win->x2)
  1252.             {
  1253.             win->cx=win->x1+1;
  1254.             win->cy++;
  1255.             }
  1256.         if(win->cy >= win->y2)
  1257.             scrollwin(win);
  1258.         if(*str=='\b')
  1259.             {
  1260.             if(win->cx>1)
  1261.                 win->cx--;
  1262.             str++;
  1263.             continue;
  1264.             }
  1265.         if(*str=='\n')
  1266.             {
  1267.             win->cx=win->x1+1;
  1268.             win->cy++;
  1269.             str++;
  1270.             continue;
  1271.             }
  1272.         *(win->screen+(win->cx++)+(win->cy*80))=*(str++)|win->text<<8;
  1273.         }
  1274.     }
  1275.  
  1276. void scrollwin(WIN *win)
  1277.     {
  1278.     int x,y;
  1279.     win->cx=win->x1+1;
  1280.     win->cy=win->y2-1;
  1281.     y=win->y1+1;
  1282.     while(y<(win->y2-1))
  1283.         {
  1284.         y++;
  1285.         for(x=win->x1+1;x<(win->x2);x++)
  1286.             *(win->screen+x+((y-1)*80))=*(win->screen+x+(y*80));
  1287.         }
  1288.     for(x=win->x1+1;x<(win->x2);x++)
  1289.         *(win->screen+x+(y*80))=32|win->text<<8;
  1290.     }
  1291.  
  1292. void openwin(WIN *win)
  1293.     {
  1294.     struct text_info tinfo;
  1295.     int x,y,h,s;
  1296.     gettextinfo(&tinfo);
  1297.     if(tinfo.currmode==MONO)
  1298.         {
  1299.         win->screen=(int far *)0xB0000000;
  1300.         win->border=7;
  1301.         win->text=15;
  1302.         win->header=15;
  1303.         }
  1304.     else
  1305.         win->screen=(int far *)0xB8000000;
  1306.  
  1307.     win->cx=win->x1+1;
  1308.     win->cy=win->y1+1;
  1309.     x=win->x1;
  1310.     y=win->y1;
  1311.     h=win->y2-y;
  1312.     *(win->screen+x+(y*80))=201|win->border<<8;
  1313.     *(win->screen+(++x)+(y*80))=181|win->border<<8;
  1314.     for(s=0;s<strlen(win->title);s++)
  1315.         *(win->screen+(++x)+(y*80))=*(win->title+s)|win->header<<8;
  1316.     *(win->screen+(++x)+(y*80))=198|win->border<<8;
  1317.     while(x<(win->x2-1))
  1318.         *(win->screen+(++x)+(y*80))=205|win->border<<8;
  1319.     *(win->screen+(++x)+(y*80))=187|win->border<<8;
  1320.     while(--h)
  1321.         {
  1322.         x=win->x1;
  1323.         *(win->screen+x+(++y*80))=186|win->border<<8;
  1324.         while(x<(win->x2-1))
  1325.             *(win->screen+(++x)+(y*80))=32|win->text<<8;
  1326.         *(win->screen+(++x)+(y*80))=186|win->border<<8;
  1327.         *(win->screen+(++x)+(y*80))&=0xfff;
  1328.         }
  1329.     x=win->x1;
  1330.     y++;
  1331.     *(win->screen+x+(y*80))=200|win->border<<8;
  1332.     while(x<(win->x2-1))
  1333.         *(win->screen+(++x)+(y*80))=205|win->border<<8;
  1334.     *(win->screen+(++x)+(y*80))=188|win->border<<8;
  1335.     *(win->screen+(++x)+(y*80))&=0xfff;
  1336.     x=win->x1+1;
  1337.     y++;
  1338.     while(x<(win->x2+1))
  1339.         *(win->screen+(++x)+(y*80))&=0xfff;
  1340.     }
  1341.  
  1342. void wallpaper(WIN *win)
  1343.     {
  1344.     struct text_info tinfo;
  1345.     int x,s;
  1346.     gettextinfo(&tinfo);
  1347.     if(tinfo.currmode==MONO)
  1348.         {
  1349.         win->screen=(int far *)0xB0000000;
  1350.         win->border=7;
  1351.         win->text=15;
  1352.         win->header=15;
  1353.         }
  1354.     else
  1355.         win->screen=(int far *)0xB8000000;
  1356.  
  1357.     for(x=0,s=0;s<strlen(win->title);s++)
  1358.         *(win->screen+(x++))=*(win->title+s)|win->header<<8;
  1359.     while(x<80)
  1360.         *(win->screen+(x++))=32|win->header<<8;
  1361.     for(x=80;x<1920;x++)
  1362.         *(win->screen+x)=176|win->border<<8;
  1363.     }
  1364.